package others.swing.p018;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;//事件
import java.awt.event.ActionListener;//监听
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;//按钮
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;//菜单
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;//文件

/**
 * 计算器-版本三
 */
public class Calculator extends WindowAdapter implements ActionListener {
    String foreNum = null;// 输入的第一个数
    String currOpr = null;// 当前操作运算符
    String currNum = null;// 输入的第二个数
    String copyStr;// 复制字符串
    static String save = null;// 保存tf2的信息，在tf1显示
    boolean keyIsClicked = true;// 记录键盘按钮是否可用
    JFrame f;
    JTextField tf1, tf2;
    JMenuBar bar;
    JMenu menuEdit, menuView, menuHelp;
    JMenuItem menuEditCopy, menuEditPaste, menuEditRecord, menuScan, menuHelpAbout, menuSee;
    JPanel p1, p2, p3, p4;// , p4, p5, p6,p7,p8,p9,p10;
    JButton bt0, bt1, bt2, bt3, bt4, bt5, bt6, bt7, bt8, bt9;
    JButton btBack, btCe, btC, btExit;
    JButton btSqrt, btPercent, btReciprocal, btSin, btCos, btTan, btExp,
            bt10ofx, btX2, btX3, btN, btLog, btLn;
    JButton btMinus, btPoint, btEqual, btAdd, btNegative, btMult, btDiv;

    public Calculator() {
        frame();// 框架
        menu();// 菜单
        UI();// UI设计
        // 页面组件需要拖动才显示的问题
        // https://blog.csdn.net/qq_40101217/article/details/107136265
        f.setVisible(true);
    }

    public void frame() {
        f = new JFrame("Jack魏计算器");
        f.setSize(580, 550);
        f.setLocation(300, 300);
        f.getContentPane().setBackground(Color.LIGHT_GRAY);
//        f.setResizable(true);// 能改变窗体大小
        f.setLayout(new BorderLayout());
    }

    //工具栏设置
    public void menu() {
        bar = new JMenuBar();
        menuEdit = new JMenu("编辑(E)");
        menuView = new JMenu("查看(V)");
        menuHelp = new JMenu("帮助(H)");
        menuEditRecord = new JMenu("历史记录(Y)");
        menuEditCopy = new JMenuItem("复制(C)");
        menuEditPaste = new JMenuItem("粘贴(V)");
        menuScan = new JMenuItem("历史记录(s)");
        menuHelpAbout = new JMenuItem("关于计算器(A)");
        menuSee = new JMenuItem("查看帮助(B)");
        bar.add(menuEdit);//创建编辑文件
        bar.add(menuView);//创建查看文件
        bar.add(menuHelp);//创建帮助文件
        f.setJMenuBar(bar);
        menuEdit.add(menuEditCopy);//在编辑文件中创建复制文件
        menuEdit.add(menuEditPaste);
        menuEdit.add(menuEditRecord);
        menuView.add(menuScan);//在查看文件中创建历史记录文件
        menuHelp.add(menuHelpAbout);//在帮助文件中创建关于计算器文件
        menuHelp.add(menuSee);
        menuEditCopy.addActionListener(this);//实现监听
        menuEditPaste.addActionListener(this);
        menuEditRecord.addActionListener(this);
        menuScan.addActionListener(this);
        menuHelpAbout.addActionListener(this);
        menuSee.addActionListener(this);
    }

    public void UI() {
        tf1 = new JTextField(15);
        tf1.setText(" =");
        tf1.setEditable(false);// 不可编辑
        tf1.setHorizontalAlignment(JTextField.RIGHT);// 从右侧输入数据
        tf2 = new JTextField(15);
        tf2.setText("0.0");
        tf2.setEditable(false);// 不可编辑
        tf2.setHorizontalAlignment(JTextField.RIGHT);// 从右侧输入数据
        p1 = new JPanel(new GridLayout(2, 1));
        p2 = new JPanel(new BorderLayout());
        p3 = new JPanel();
        p4 = new JPanel(new GridLayout(6, 5));
        btBack = new JButton("<—");
        btCe = new JButton("Ce");
        btC = new JButton("C");
        btExit = new JButton("off");
        btSin = new JButton("sin");
        btCos = new JButton("cos");
        btTan = new JButton("tan");
        btExp = new JButton("exp");
        bt10ofx = new JButton("10^x");
        btX2 = new JButton("x^2");
        btX3 = new JButton("x^3");
        btN = new JButton(" n! ");
        btLog = new JButton("log");
        btLn = new JButton(" ln ");
        bt7 = new JButton("7");
        bt8 = new JButton("8");
        bt9 = new JButton("9");
        btDiv = new JButton("/");
        btSqrt = new JButton("sqrt");
        bt4 = new JButton("4");
        bt5 = new JButton("5");
        bt6 = new JButton("6");
        btMult = new JButton("*");
        btPercent = new JButton("  % ");
        bt1 = new JButton("1");
        bt2 = new JButton("2");
        bt3 = new JButton("3");
        btMinus = new JButton("-");
        btReciprocal = new JButton(" 1/x");
        bt0 = new JButton("0");
        btPoint = new JButton(".");
        btEqual = new JButton("=");
        btAdd = new JButton("+");
        btNegative = new JButton(" +/-");

        p3.add(btBack);// 逐个删除
        p3.add(btCe);// 清除当前输入的数据或符号
        p3.add(btC);// 清除（clear）键
        p3.add(btExit);// 退出键
        p4.add(btSin);// sin
        p4.add(btCos);// cos
        p4.add(btTan);// tan
        p4.add(btExp);// 返回欧拉数 e 的 double 次幂的值
        p4.add(bt10ofx);// 返回10的x次方
        p4.add(btX2);// x的平方
        p4.add(btX3);// x的立方
        p4.add(btN);// n的阶乘
        p4.add(btLog);// log函数
        p4.add(btLn);// ln函数
        p4.add(bt7);
        p4.add(bt8);
        p4.add(bt9);
        p4.add(btDiv);// 除号
        p4.add(btSqrt);// 根号
        p4.add(bt4);
        p4.add(bt5);
        p4.add(bt6);
        p4.add(btMult);// 乘号
        p4.add(btPercent);// 百分号
        p4.add(bt1);
        p4.add(bt2);
        p4.add(bt3);
        p4.add(btMinus);// 减号
        p4.add(btReciprocal);// 倒数
        p4.add(bt0);
        p4.add(btPoint);
        p4.add(btEqual);// 等号
        p4.add(btAdd);
        p4.add(btNegative);// 正负符号
        p1.add(tf1);
        p1.add(tf2);
        f.add(p1, BorderLayout.NORTH);
        f.add(p2, BorderLayout.CENTER);
        p2.add(p3, BorderLayout.NORTH);
        p2.add(p4, BorderLayout.CENTER);
        // 设置按键的前景色
        btBack.setForeground(new Color(0, 255, 0));
        btCe.setForeground(new Color(0, 255, 0));
        btC.setForeground(new Color(0, 255, 0));
        btExit.setForeground(new Color(0, 255, 0));
        btEqual.setForeground(new Color(255, 0, 0));//数字以及小数点和等号的前景色
        bt0.setForeground(new Color(255, 0, 0));
        bt1.setForeground(new Color(255, 0, 0));
        bt3.setForeground(new Color(255, 0, 0));
        bt4.setForeground(new Color(255, 0, 0));
        bt6.setForeground(new Color(255, 0, 0));
        bt7.setForeground(new Color(255, 0, 0));
        bt9.setForeground(new Color(255, 0, 0));
        bt8.setForeground(new Color(255, 0, 0));
        bt5.setForeground(new Color(255, 0, 0));
        bt2.setForeground(new Color(255, 0, 0));
        btPoint.setForeground(new Color(255, 0, 0));
        btSqrt.setForeground(new Color(0, 0, 255));//复杂运算的符号
        btPercent.setForeground(new Color(0, 0, 255));
        btReciprocal.setForeground(new Color(0, 0, 255));
        btNegative.setForeground(new Color(0, 0, 255));
        btSin.setForeground(new Color(0, 0, 255));
        btCos.setForeground(new Color(0, 0, 255));
        btTan.setForeground(new Color(0, 0, 255));
        btExp.setForeground(new Color(0, 0, 255));
        bt10ofx.setForeground(new Color(0, 0, 255));
        btX2.setForeground(new Color(0, 0, 255));
        btX3.setForeground(new Color(0, 0, 255));
        btN.setForeground(new Color(0, 0, 255));
        btLog.setForeground(new Color(0, 0, 255));
        btLn.setForeground(new Color(0, 0, 255));
        btAdd.setForeground(new Color(0, 100, 100));//加减乘除符号的前景色
        btMult.setForeground(new Color(0, 100, 100));
        btDiv.setForeground(new Color(0, 100, 100));
        btMinus.setForeground(new Color(0, 100, 100));
        // 注册监听
        bt1.addActionListener(this);
        bt2.addActionListener(this);
        bt3.addActionListener(this);
        bt4.addActionListener(this);
        bt5.addActionListener(this);
        bt6.addActionListener(this);
        bt7.addActionListener(this);
        bt8.addActionListener(this);
        bt9.addActionListener(this);
        bt0.addActionListener(this);
        btAdd.addActionListener(this);
        btMinus.addActionListener(this);
        btMult.addActionListener(this);
        btDiv.addActionListener(this);
        btEqual.addActionListener(this);
        btPoint.addActionListener(this);
        btSqrt.addActionListener(this);
        btPercent.addActionListener(this);
        btReciprocal.addActionListener(this);
        btNegative.addActionListener(this);
        btBack.addActionListener(this);
        btCe.addActionListener(this);
        btC.addActionListener(this);
        btExit.addActionListener(this);
        btSin.addActionListener(this);
        btCos.addActionListener(this);
        btTan.addActionListener(this);
        btExp.addActionListener(this);
        bt10ofx.addActionListener(this);
        btX2.addActionListener(this);
        btX3.addActionListener(this);
        btN.addActionListener(this);
        btLog.addActionListener(this);
        btLn.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO 自动生成方法存根
        Object obj = e.getSource();
        // 输入数字
        if (obj == bt1 || obj == bt2 || obj == bt3 || obj == bt4 || obj == bt5
                || obj == bt6 || obj == bt7 || obj == bt8 || obj == bt9
                || obj == bt0) {
            if (keyIsClicked) {
                tf2.setText(e.getActionCommand());
                save = tf2.getText();
                tf1.setText(save);
            } else {
                tf2.setText(tf2.getText() + e.getActionCommand());
                save = tf2.getText();
                tf1.setText(save);
            }
            keyIsClicked = false;
        }
        // 小数点
        else if (obj == btPoint) {
            if (!keyIsClicked) {
                tf2.setText(tf2.getText() + '.');
            }
        }
        // 实现开根号
        else if (obj == btSqrt) {
            save = tf2.getText();
            if (tf2.getText().charAt(0) == '-') {// 返回字符串第一个字符
                tf2.setText("错误！输入无效");
            } else {
                tf2.setText(Double.toString(Math.sqrt(Double.parseDouble(save))));
            }
            tf1.setText("x= " + save + " √" + " =");
            keyIsClicked = true;
        }
        // 实现倒数
        else if (obj == btReciprocal) {
            save = tf2.getText();
            for (int i = 0; i < save.length(); i++) {
                if (save.charAt(i) == '0') {
                    tf2.setText("错误！零不能求倒数");
                } else {
                    String s = Double.toString(1 / Double.parseDouble(save));
                    foreNum = tf2.getText();
                    tf2.setText(s);
                    tf1.setText("x= " + save + " 1/x" + " =");
                    keyIsClicked = true;
                }
            }
        }
        // 实现sin
        else if (obj == btSin) {
            save = tf2.getText();
            tf2.setText(Double.toString(Math.sin(Double.parseDouble(save))));
            tf1.setText("x= " + save + " sinx" + " =");
            keyIsClicked = true;
        }
        // 实现cos
        else if (obj == btCos) {
            save = tf2.getText();
            tf2.setText(Double.toString(Math.cos(Double.parseDouble(save))));
            tf1.setText("x= " + save + " cosx" + " =");
            keyIsClicked = true;
        }
        // 实现tan
        else if (obj == btTan) {
            save = tf2.getText();
            tf2.setText(Double.toString(Math.tan(Double.parseDouble(tf2
                    .getText()))));
            tf1.setText("x= " + save + " tanx" + " =");
            keyIsClicked = true;
        }
        // 实现exp
        else if (obj == btExp) {
            save = tf2.getText();
            tf2.setText(Double.toString(Math.tan(Double.parseDouble(tf2
                    .getText()))));
            tf1.setText("x= " + save + " exp(x)" + " =");
            keyIsClicked = true;
        }
        // 实现10的x次方
        else if (obj == bt10ofx) {
            double a, s = 1;
            save = tf2.getText();
            a = Double.parseDouble(save);
            for (int i = 1; i <= a; i++) {
                s *= 10;
            }
            tf2.setText(Double.toString(s));
            tf1.setText("x= " + save + " 10^x" + " =");
            keyIsClicked = true;
        }
        // 实现x的平方
        else if (obj == btX2) {
            double x;
            save = tf2.getText();
            x = Double.parseDouble(save);
            tf2.setText(Double.toString(x * x));
            tf1.setText("x= " + save + "  x^2" + " =");
            keyIsClicked = true;
        }
        // 实现x的立方
        else if (obj == btX3) {
            double x;
            save = tf2.getText();
            x = Double.parseDouble(save);
            tf2.setText(Double.toString(x * x * x));
            tf1.setText("x= " + save + "  x^3" + " =");
            keyIsClicked = true;
        }
        // 实现n的阶乘
        else if (obj == btN) {
            double a, s = 1;
            save = tf2.getText();
            a = Double.parseDouble(save);
            for (int i = 1; i <= a; i++) {
                s *= i;
            }
            tf2.setText(Double.toString(s));
            tf1.setText("n= " + save + "  n!" + " =");
            keyIsClicked = true;
        }
        // 实现log
        else if (obj == btLog) {
            save = tf2.getText();
            tf2.setText(Double.toString(Math.log10(Double.parseDouble(tf2
                    .getText()))));
            tf1.setText("x= " + save + "  logx" + " =");
            keyIsClicked = true;
        }
        // 实现ln
        else if (obj == btLn) {
            save = tf2.getText();
            tf2.setText(Double.toString(Math.log(Double.parseDouble(tf2
                    .getText()))));
            tf1.setText("x= " + save + "  lnx" + " =");
            keyIsClicked = true;
        }
        // 实现+/-符号
        else if (obj == btNegative) {
            String s = tf2.getText();
            for (int m = 0; m < s.length(); m++) {
                if (!(s.charAt(m) >= '0' && s.charAt(m) <= '9'
                        || s.charAt(m) == '.' || s.charAt(m) == '-')) {
                    break;
                }
            }
            // 如果当前字符串首字母有-号,代表现在是个负数,再按下时,则将首符号去掉
            if (s.charAt(0) == '-') {
                tf2.setText("");
                for (int m = 1; m < s.length(); m++) {
                    char a = s.charAt(m);
                    tf2.setText(tf2.getText() + a);
                    save = save + tf2.getText();
                    tf1.setText(save);
                }
            }
            // 如果当前字符串第一个字符不是负号，则添加一个符号在首字母处
            else {
                tf2.setText('-' + s);
                tf1.setText(tf2.getText());
            }
        }
        // 实现%功能
        else if (obj == btPercent) {
            boolean isNumber = true;
            if (isNumber) {
                tf2.setText(String.valueOf(Double.parseDouble(tf2.getText()) / 100));
            } else {
                tf2.setText("错误");
            }
        }
        // 实现四则运算
        else if (obj == btAdd || obj == btMinus || obj == btDiv
                || obj == btMult) {
            if (!keyIsClicked) {
                currNum = tf2.getText();
                try {
                    if ("+".equals(currOpr)) {
                        tf2.setText(String.valueOf(Double.parseDouble(foreNum)
                                + Double.parseDouble(currNum)));// valueOf()要把参数中给的值，转化为String类型
                    } else if ("-".equals(currOpr)) {
                        tf2.setText(String.valueOf(Double.parseDouble(foreNum)
                                - Double.parseDouble(currNum)));
                    } else if ("*".equals(currOpr)) {
                        tf2.setText(String.valueOf(Double.parseDouble(foreNum)
                                * Double.parseDouble(currNum)));
                    } else if ("/".equals(currOpr)) {
                        if (Double.parseDouble(tf2.getText()) == 0) {
                            tf2.setText("除数不能为零");
                        } else {
                            tf2.setText(String.valueOf(Double
                                    .parseDouble(foreNum)
                                    / Double.parseDouble(currNum)));
                        }
                    }
                } catch (NumberFormatException exc) {
                    System.out.println("请先输入计算的数字！");
                    exc.printStackTrace();
                }
            }
            foreNum = tf2.getText();
            tf2.setText("");
            currOpr = e.getActionCommand();
            keyIsClicked = false;
        }
        // 实现等号
        else if (obj == btEqual) {
            currNum = tf2.getText();
            if ("+".equals(currOpr)) {
                tf2.setText(String.valueOf(Double.parseDouble(foreNum)
                        + Double.parseDouble(currNum)));
                tf1.setText(foreNum + "+" + currNum + " =");
            } else if ("-".equals(currOpr)) {
                tf2.setText(String.valueOf(Double.parseDouble(foreNum)
                        - Double.parseDouble(currNum)));
                tf1.setText(foreNum + "-" + currNum + " =");
            } else if ("*".equals(currOpr)) {
                tf2.setText(String.valueOf(Double.parseDouble(foreNum)
                        * Double.parseDouble(currNum)));
                tf1.setText(foreNum + "*" + currNum + " =");
            } else if ("/".equals(currOpr)) {
                if (Double.parseDouble(tf2.getText()) == 0) {
                    tf2.setText("除数不能为零");
                } else {
                    tf2.setText(String.valueOf(Double.parseDouble(foreNum)
                            / Double.parseDouble(currNum)));
                    tf1.setText(foreNum + "/" + currNum + " =");
                }
            }
            currOpr = e.getActionCommand();
            keyIsClicked = true;
        }
        // 实现Backspace功能
        else if (obj == btBack) {
            String s = tf2.getText();
            tf2.setText("");
            for (int m = 0; m < s.length() - 1; m++) {
                char a = s.charAt(m);
                tf2.setText(tf2.getText() + a);
                keyIsClicked = true;
            }
        }
        // 实现Ce功能
        else if (obj == btCe) {
            tf2.setText("");
        }
        // 实现C功能
        else if (obj == btC) {
            foreNum = currNum = save = null;
            keyIsClicked = true;
            tf2.setText("0.0");
            tf1.setText(" =");
        }
        // 实现退出功能
        else if (obj == btExit) {
            System.exit(0);
        }
        // 实现复制
        else if (obj == menuEditCopy) {
            copyStr = tf2.getText();
        }
        // 实现粘贴
        else if (obj == menuEditPaste) {
            tf2.setText(copyStr);
        }
        // 实现查看主题
        else if (obj == menuScan) {
            ImageIcon icon = new ImageIcon("计算器.jpg");
            JLabel label = new JLabel(icon);
            JOptionPane.showMessageDialog(f, label, "查看主题",
                    JOptionPane.PLAIN_MESSAGE);
        }
        // 实现帮助主题
        else if (obj == menuHelpAbout) {
            ImageIcon icon = new ImageIcon("介绍.jpg");
            JLabel label = new JLabel(icon);
            JOptionPane.showMessageDialog(f, label, "帮助主题", JOptionPane.PLAIN_MESSAGE);// JOptionPane  // 有助于方便地弹出要求用户提供值或向其发出通知的标准对话框
        } // showMessageDialog 告知用户某事已发生。
    } // PLAIN_MESSAGE未使用图标

    @Override
    public void windowClosing(WindowEvent arg0) {
        System.exit(0);
    }

    public static void main(String[] args) {
        new Calculator();
    }
}
